<template>
    <div>
        <div class="lyric">
            <!-- 歌曲背景图 -->
            <div class="music_bg" v-if="musicData && musicData.al.picUrl"
                :style="`background-image: url(${musicData.al.picUrl});`"></div>
            <!-- 歌曲信息 -->
            <div class="music_info">
                <!-- 头部 -->
                <div class="lyric-header" v-if="musicData">
                    <div class="btn-back" @click="goBack">返回</div>
                    <h3>{{ musicData.name | sliceName }}</h3>
                </div>
                <!-- 封面 -->
                <div @click="controlFunc" class="lyric-section" v-if="musicData">
                    <div class="image-box">
                        <!-- 图标(磁头) -->
                        <div :class="['tool', isPause == true ? 'off' : '']"></div>
                        <ul :class="['animated', isPause == true ? 'off' : '']">
                            <li>
                                <img v-if="musicData.al.picUrl" :src="musicData.al.picUrl" alt="">
                            </li>
                        </ul>
                        <div class="control">
                            <!-- 播放图标 -->
                            <span class="icon" v-if="isPause"></span>
                        </div>
                    </div>
                </div>
                <!-- 歌词 -->
                <div class="lyric-section">
                    <div class="text-box" v-if="lyricArr.length != 0">
                        <ul :style="`transform:translateY(-${num * height}px)`">
                            <li v-for="(item, i) in lyricArr" :class="num == i ? 'active' : ''">
                                {{ item.txt }}
                            </li>
                        </ul>
                    </div>
                    <!-- 因为条件渲染 v-if 指令的使用，标签还没渲染，所以获取不到指定元素。故放多一个元素，记录样式。 -->
                    <div class="div" ref="div"></div>
                </div>
            </div>
        </div>
        <div v-if="!musicData">
            <h3 class="msg">正在检索...</h3>
        </div>
        <!-- 音频文件 -->
        <div class="audio-container">
            <audio controls autoplay ref="audio" @ended="addEndEvent"
                :src="`https://music.163.com/song/media/outer/url?id=${musicid}.mp3`"></audio>
        </div>
        <!-- 进度条 -->
        <div class="progress">
            <div class="progress-box" ref="progressBox">
                <div class="left">{{ cur | formatTime }}</div>
                <div class="center">
                    <ul ref="ul">
                        <li ref="li" :style="`width:${w}px;`">
                            <span ref="span" class="circle" :style="`left:${x}px;`"></span>
                        </li>
                    </ul>
                </div>
                <div class="right">{{ duration | formatTime }}</div>
            </div>
        </div>
    </div>
</template>

<style lang="scss">
@import '../../static/style/variable.scss';

@keyframes loop {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

// 旋转封面
.animated {
    animation: loop 5s infinite linear;
}

.animated.off {
    animation-play-state: paused;
}

.progress {
    width: 100%;
    padding: 0 .2667rem;
    position: absolute;
    bottom: 1.3333rem;
    left: 0;
    z-index: 10000;

    .progress-box {
        width: 100%;
        height: .8rem;
        padding: 0 1.6rem;
        position: relative;
        box-sizing: border-box;

        .left,
        .right {
            width: 1.6rem;
            height: .8rem;
            // background-color: red;
            position: absolute;
            top: 0;
            line-height: .8rem;
            text-align: center;
            color: #fff;
        }

        .left {
            left: 0;
        }

        .right {
            right: 0;
        }

        .center {
            width: 100%;
            height: .8rem;
            display: flex;
            align-items: center;

            ul {
                height: .08rem;
                width: 100%;
                background-color: #ccc;
                position: relative;

                li {
                    height: .08rem;
                    width: 0px;
                    background-color: $bgColor;
                }

                .circle {
                    position: absolute;
                    left: 0;
                    top: -0.08rem;
                    // 19 - 3 ) / 2 = 8
                    width: .24rem;
                    height: .24rem;
                    background-color: $bgColor;
                    border-radius: 50%;
                    box-shadow: 0 0 5px #fff;
                }
            }
        }
    }
}

.audio-container {
    width: 0;
    height: 0;

    audio {
        width: 0;
        height: 0;
        opacity: 0;
    }
}

.msg {
    text-align: center;
    padding: 1.3333rem 0;
    background-color: #f0f0f0;
}

.music_bg {
    /* 固定定位 */
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background-color: #ccc;
    background-size: cover;
    /* 设置背景模糊 */
    filter: blur(30px);
    transform: scale(1.5);
}

.music_info {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10000;
    width: 100%;
    height: 100%;
}

.lyric-header {
    width: 100%;
    height: 1.6rem;
    line-height: 1.6rem;
    text-align: center;
    background-color: rgba(0, 0, 0, .5);
    color: #fff;
    position: relative;

    .btn-back {
        position: absolute;
        left: .2667rem;
        color: #fff;
    }

    h3 {
        font-weight: normal;
        font-size: 16px;
    }
}

.lyric-section {
    width: 100%;
}

.image-box {
    height: 7.4667rem;
    width: 100%;
    display: flex;
    justify-content: center;
    // background-color: red;
    align-items: center;
    position: relative;
    transform-origin: left top;

    .control {
        .icon {
            position: absolute;
            left: 50%;
            top: 50%;
            width: 1.6rem;
            height: 1.6rem;
            margin-left: -0.8rem;
            margin-top: -0.8rem;
            background-image: url(../../static/images/i-play.png);
            background-size: cover;
        }
    }

    .tool {
        width: 6.6667rem * (1/3);
        height: 10.9333rem * (1/3);
        background-image: url(../../static/images/needle-ab.png);
        background-size: 6.6667rem * (1/3) 10.9333rem* (1/3);
        position: absolute;
        left: calc(50% - .5333rem);
        top: -0.5333rem;
        z-index: 100000;
        // 设置旋转中心
        transform-origin: left top;
        transition: all .5s;
        // transform: rotateZ(-25deg);
    }

    .tool.off {
        transform: rotateZ(-25deg);
    }

    ul {
        width: 6.4rem;
        height: 6.4rem;
        border: 10px solid rgba(255, 255, 255, .2);
        overflow: hidden;
        border-radius: 50%;
        padding: .8rem;
        background-color: #1E1E1E;

        li {
            width: 100%;
            height: 100%;
            overflow: hidden;
            border-radius: 50%;
            text-align: center;
            line-height: 100%;
            position: relative;

            img {
                width: 100%;
                vertical-align: middle;
            }
        }
    }
}

// 占位置的div标签
.div {
    height: .8rem;
}

.text-box {
    width: 100%;
    height: 150px;
    overflow: hidden;

    // background-color: red;
    ul {
        transform: translateY(-30px);
        transition: all .3s;
        width: 100%;
        margin-top: 60px;

        li {
            color: #fff;
            text-align: center;
            height: .8rem;
            line-height: .8rem;
            transition: all .2s;
        }

        .active {
            color: $activeColor;
            font-size: 17px;
        }
    }
}
</style>
<script>
// 导入接口文件
import { addLyric, addPlayDetail } from '@/request';
export default {
    // 组件名称
    name: 'lyric',
    // 添加数据
    data() {
        return {
            // 是否按下
            isTouch: false,
            // 记录歌曲信息
            musicData: null,
            // 记录歌词数组
            lyricArr: [],
            // 记录最新音乐
            songList: [],
            // 音频总时长
            duration: 0,
            // 音频当前播放时长
            cur: 0,
            // 记录音乐ID
            musicid: '',
            // 记录歌曲的索引值
            index: 0,
            // 歌词的索引值
            num: -1,
            // 是否暂停音乐
            isPause: false,
            // 记录ul元素
            ul: null,
            // 记录li元素
            li: null,
            // 记录span元素
            span: null,
            // 记录ul元素的宽度
            width: 0,
            // 计算li标签的宽度
            w: 0,
            // 当前位置
            x: 0,
            // 记录span标签的宽度
            spanWidth: 0,
            // 记录每一行歌词的高度
            height: 0,
            page: 0,
            pageSize: 20,
        }
    },
    // 钩子1
    created() {
        // 初始化
    },
    // 过滤器
    filters: {
        // 格式化 时分秒
        formatTime(value) {
            // 秒数
            let h, m, s;
            // 处理秒数
            h = Math.floor(value / 3600);
            m = Math.floor(value % 3600 / 60);
            s = Math.floor(value % 60);

            // 补个0
            h = h < 10 ? '0' + h : h;
            m = m < 10 ? '0' + m : m;
            s = s < 10 ? '0' + s : s;
            // 返回处理结果
            // return `${h}:${m}:${s}`;
            return `${m}:${s}`;
        },
        // 设置歌词标题 控制字符串长度
        sliceName(value) {
            if (typeof value == 'string') {
                let str = value.slice(0, 6);
                if (str.length < 6) {
                    return str
                } else {
                    return str + ". . .";
                }
            }
            else {
                return value
            }
        }
    },
    // 侦听器
    watch: {
        // 监听音乐数据的变化
        musicData: {
            deep: true,
            handler(newVal, oldVal) {
                // 根据歌曲的ID获取歌词
                this.getLyricFunc(newVal.id);
            }
        },
        // 观察音频文件的播放
        cur(newVal, oldVal) {
            // 加多一个判断，减少报错
            if (this.lyricArr.length == 0) {
                return;
            }
            // 循环歌词数组，根据时间设置歌词下标
            for (let i = 0; i < this.lyricArr.length - 1; i++) {
                // 判断音频文件当前播放进度 获取歌词文本的索引值
                if (newVal > this.lyricArr[i].times && newVal < this.lyricArr[i + 1].times) {
                    // 获取歌词下标！！！！
                    this.num = i;
                    break;
                }
            }
            // console.log("第" + this.num + "行歌词")
        },
        // 观察ID变化
        musicid(newVal, oldVal) {
            // 切换歌曲时检查ID是否变化
            console.log('新ID:', newVal, '旧ID:', oldVal)
        }
    },
    // 编写方法
    methods: {
        // 获取歌词方法
        getLyricFunc(id) {
            // 调用获取歌词的接口
            addLyric({ id }).then(content => {
                // console.log(content)
                if (content.code == 200) {
                    // 歌词字符串
                    let text = content.lrc.lyric;
                    // console.log(text)
                    this.parseLyric(text);
                }
            })
        },
        // 返回主页
        goBack() {
            // this.$router.push({ path: '/home/hotmusic', id: this.rid })
            this.$router.go(-1);
        },
        // 解析歌词
        parseLyric(lyric) {
            // 把歌词字符串切割成数组
            let arr = lyric.split('\n');
            // console.log(arr); 
            // 匹配歌词的正则表达式
            let rep = /\[(\d{2,}):(\d{2,})\.(\d{2,})\](.*)/;
            // 定义空数组
            // let newArr = [];
            // 循环歌词数组
            console.log(lyric)
            // arr.forEach( text => {})
            let newArr = arr.map(text => {
                if (rep.test(text)) {
                    // 提起歌词信息（时间，歌词文本）
                    let arr2 = rep.exec(text)
                    
                    // 提取时间
                    let m = arr2[1] - 0;
                    let s = arr2[2] - 0;
                    let ms = arr2[3] - 0;
                    let times = m * 60 + s + ms / 1000;
                    // 提取歌词文本(清除两端空格字符)
                    let txt = arr2[4].trim();
                    return {
                        times,
                        txt
                    }
                }
            })
            // console.log(newArr);
            // 用数组记录整首歌的时间和文本
            // this.lyricArr = newArr;
            this.lyricArr = newArr.splice(0, newArr.length - 1);
        },
        // 获取最新音乐
        async getPlayDetail(id) {
            await addPlayDetail({ id }).then(
                content => {
                    console.log(content)
                    if (content.code == 200) {
                        let { playlist: { trackIds, tracks } } = content
                        let arr = tracks.map((item, i) => {
                            let { al, ar, name, publishTime, id } = item;
                            let str = '';
                            // console.log(ar);
                            if (Array.isArray(ar)) {
                                ar.forEach(opt => {
                                    str += opt.name + ' / '
                                })
                                str = str.substring(0, str.length - 2);
                            }

                            if (item.id == id) {
                                this.musicData = item;
                                this.index = i;
                            }
                            return { al, ar, name, publishTime, str, id };
                        })
                        // 截取是10条记录
                        let start = this.page * this.pageSize;
                        let end = start + this.pageSize;
                        console.log(arr.slice(start, end))
                        this.songList = arr.slice(start, end);
                    }
                }
            )
        },
        // 初始化歌曲信息
        init() {
            this.$nextTick(() => {
                // 判断页面是否存audio元素
                if (this.$refs['audio']) {
                    this.audio = this.$refs['audio'];
                    // console.log('元素:', this.audio);
                    // 获取音频总时长
                    this.getAudioDuration();
                    // 获取音频当前播放时长
                    this.getAudioCurrent();
                }

                // 获取ul标签
                if (this.$refs['ul']) {
                    this.ul = this.$refs['ul']
                    // console.log(this.ul)
                    // let v = getComputedStyle(this.ul)['width']
                    this.width = parseFloat(getComputedStyle(this.ul)['width']);
                    // console.log('--->',this.width);
                }

                // 获取li标签
                if (this.$refs['li']) {
                    this.li = this.$refs['li']
                }

                // 获取span标签
                if (this.$refs['span']) {
                    this.span = this.$refs['span']
                    this.spanWidth = parseFloat(getComputedStyle(this.span)['width']);
                    // console.log('--->',this.spanWidth)
                }
            })
        },
        // 获取歌曲的总时长
        getAudioDuration() {
            // 判断页面是否存audio元素
            this.$nextTick(() => {
                if (this.$refs['audio']) {
                    this.audio = this.$refs['audio'];
                    this.audio.oncanplay = () => {
                        // 获取音频文件总时长
                        this.duration = this.audio.duration;
                        console.log("总时长:", this.duration)
                    }
                }
            })
        },
        // 获取歌曲的当前播放时长
        getAudioCurrent() {
            this.$nextTick(() => {
                if (this.$refs['audio']) {
                    this.audio.ontimeupdate = () => {
                        this.cur = this.audio.currentTime;
                        let demo = (this.cur / this.duration);
                        let v = demo * (this.width - this.spanWidth);
                        //li元素的宽度
                        this.w = v;
                        //spab元素的位置
                        this.x = v;
                    }
                }
            })
        },
        // 监听音乐播放结束
        addEndEvent() {
            // 当前音频播放结束
            console.log("上一首歌曲播放结束")
            this.index++;
            if (this.index > this.songList.length - 1) {
                this.index = 0;
            }
            // 赋值给musicid
            this.musicid = this.songList[this.index].id;
            // 切换那一首歌曲
            this.musicData = this.songList[this.index];
            // 获取歌曲
            this.getLyricFunc(this.musicid);
            // console.log("ID:", this.musicid);
        },
        // 手指按下滑动控制音频的进度
        addTouchEvent() {
            this.$nextTick(() => {
                // 检查元素是否获取
                // console.log(this.$refs['span'])
                // console.log(this.$refs['ul'])
                // console.log(this.$refs['progress'])
                // 记录滑动进度条的参数
                this.audio = this.$refs['audio'];
                this.span = this.$refs['span'];
                this.ul = this.$refs['ul'];
                this.progressBox = this.$refs['progressBox'];
                this.width = parseFloat(getComputedStyle(this.ul)['width']);
                this.spanWidth = parseFloat(getComputedStyle(this.span)['width']);

                //  判断的目的为了减少报错
                if (this.span && this.ul && this.progressBox) {
                    this.left_1 = this.progressBox.offsetLeft;
                    this.left_2 = this.ul.offsetLeft;
                    // console.log({v1: this.left_1, v2: this.left_2})
                    // 交互行为
                    // 手指按下
                    this.span.ontouchstart = evt => {
                        this.isTouch = true;
                        // 暂停音乐
                        this.audio.pause();
                        // 手指滑动
                        document.ontouchmove = event => {
                            let { clientX } = event.touches[0];
                            let v3 = clientX - this.left_1 - this.left_2;
                            if (v3 < 0) {
                                v3 = 0
                            }
                            if (v3 > (this.width - this.spanWidth)) {
                                v3 = this.width - this.spanWidth;
                            }
                            // console.log('2.0', v3);
                            this.x = v3;
                            this.w = v3;
                            // 计算li标签宽度占ul标签宽度的多少比例
                            let demo = this.w / (this.width - this.spanWidth);
                            this.cur = demo * this.duration;
                            this.audio.currentTime = this.cur;
                        }
                    }
                    // 手指松开
                    document.ontouchend = () => {
                        document.ontouchmove = null;
                        // 手指抬起 播放音乐
                        // console.dir(this.audio);
                        // console.dir(this.audio.play);
                        if(this.isTouch){
                            this.audio.play();
                        }
                        this.isTouch = false;
                        
                    }
                }
            })
        },
        // 点击暂停音乐
        controlFunc() {
            this.$nextTick(() => {
                if (this.$refs['audio']) {
                    if (this.isPause) {
                        this.$refs['audio'].play();
                    } else {
                        this.$refs['audio'].pause();
                    }
                    this.isPause = !this.isPause;
                }
            })
        },
    },
    // 钩子2
    mounted() {
        let { id, rid } = this.$route.query;
        console.log({ id, rid })
        // 初始化数据
        this.getPlayDetail(rid);
        // 设置音乐路径
        this.musicid = id;
        // 获取每一行歌词标签的高度
        this.$nextTick(() => {
            // 获取渲染歌词标签
            // console.log(this.$refs['div'])
            if (this.$refs['div']) {
                let div = this.$refs['div'];
                this.height = parseFloat(getComputedStyle(div)['height']);
                // console.log("每行歌词的高：", this.height)
            }
        })
        //初始化
        this.init();
        // 添加触滑行为
        this.addTouchEvent();
    },
    beforeRouteLeave(to, from, next) {
        this.$nextTick(() => {
            if (this.$refs['audio']) {
                this.$refs['audio'].pause();
                this.isPause = !this.isPause;
            }
        })
        next();
    },
    beforeDestroy() {
        this.musicid = '';
        console.log('销毁..')
        this.$nextTick(() => {
            if (this.$refs['audio']) {
                this.$refs['audio'].pause();
                this.isPause = !this.isPause;
                this.audio = null;
            }
        })
    }
}
</script>